#include "headfile.h"

void key_init()
{
  gpio_init(GPIO_A,Pin_9,IU);
  gpio_init(GPIO_A,Pin_10,IU);
  gpio_init(GPIO_A,Pin_11,IU);
  gpio_init(GPIO_A,Pin_12,IU);
}

int key_scan()
{
    if (!gpio_get(GPIO_A, Pin_9))
	{
        delay_ms(20);
        while (gpio_get(GPIO_A, Pin_9) == 0);
        delay_ms(20);
        return 1;
	}
	if (!gpio_get(GPIO_A, Pin_10))
	{
        delay_ms(20);
        while (gpio_get(GPIO_A, Pin_10) == 0);
        delay_ms(20);
        return 2;
	}
	if (!gpio_get(GPIO_A, Pin_11))
	{
        delay_ms(20);
        while (gpio_get(GPIO_A, Pin_11) == 0);
        delay_ms(20);
        return 3;
	}
	if (!gpio_get(GPIO_A, Pin_12))
	{
        delay_ms(20);
        while (gpio_get(GPIO_A, Pin_12) == 0);
        delay_ms(20);
        return 4;
	}
	return 0;
}

int menu_mode = 0;
char show_str[40];

int args_index = 0;

enum arg_mode
{
    ARG_INT,
    ARG_FLOAT
};

const char* args_name[] = { "C->D a"  , "A->C bai", "A->C hui", "B->D bai", "B->D hui", "bai_dir", "zhi_angle" };
const void* args[]      = { &c_d_angle, &a_c_bai  , &a_c_hui  , &b_d_bai  , &b_d_hui  ,  &bai_dir, &zhi_angle  };
const int   args_mode[] = { ARG_FLOAT , ARG_INT   , ARG_INT   , ARG_INT   , ARG_INT   ,  ARG_INT , ARG_FLOAT   };

float change_mode[] = { 10, 5, 1, 0.5, 0.1 };
int change_index = 2;

void default_menu()
{
    sprintf(show_str,"g:%.2f", yaw_gyro);
    OLED_ShowString(1, 1, show_str);
    sprintf(show_str,"run:%d", is_running);
    OLED_ShowString(1, 11, show_str);
    sprintf(show_str,"state:%d", code_state);
    OLED_ShowString(2, 1, show_str);
    sprintf(show_str,"track:%d", track_state);
    OLED_ShowString(2, 9, show_str);
    
    sprintf(show_str,"%d:%d", track_state, (int)(track_state ? duoji_track.out : duoji_none.out));
    OLED_ShowString(3, 1, show_str);
    sprintf(show_str,"n:%d", none_nums);
    OLED_ShowString(3, 9, show_str);
    
    switch (key_scan())
    {
    case 1 :
        code_state = (code_state + 1) % (sizeof(car_running) / sizeof(car_running[0]));
        break;
    case 2 :
        is_running = 1;
        duoji_start();
        sprintf(show_str, "run:%d", is_running);
        OLED_ShowString(1, 11, show_str);
        delay_s(1);
        break;
    case 3 :
    case 4 :
        OLED_Clear();
        ++menu_mode;
        break;
    }
}

void show_arg(int index)
{
    if (index < sizeof(args_name) / sizeof(args_name[0]))
    {
        if (args_mode[index] == ARG_FLOAT)
            sprintf(show_str, "%s:%4.02f", args_name[index], *(float*)args[index]);
        if (args_mode[index] == ARG_INT)
            sprintf(show_str, "%s:%5d", args_name[index], *(int*)args[index]);
    }
    else
    {
        sprintf(show_str, "                ");
    }
}

void args_menu()
{
    sprintf(show_str, "@");
    OLED_ShowString(1, 1, show_str);
    
    show_arg(args_index);
    OLED_ShowString(1, 2, show_str);
    
    show_arg(args_index + 1);
    OLED_ShowString(2, 1, show_str);
    
    show_arg(args_index + 2);
    OLED_ShowString(3, 1, show_str);
    
    switch (key_scan())
    {
    case 1 :
        args_index++;
        if (args_index >= sizeof(args_name) / sizeof(args_name[0]))
            args_index--;
        break;
    case 2 :
        args_index--;
        if (args_index < 0)
            args_index++;
        break;
    case 3 :
        OLED_Clear();
        ++menu_mode;
        break;
    case 4 :
        OLED_Clear();
        --menu_mode;
        break;
    }
}

void modify_args()
{
    sprintf(show_str, "%s:", args_name[args_index]);
    OLED_ShowString(1, 1, show_str);
    
    if (args_mode[args_index] == ARG_FLOAT)
        sprintf(show_str, "%4.02f", *(float*)args[args_index]);
    if (args_mode[args_index] == ARG_INT)
        sprintf(show_str, "%5d", *(int*)args[args_index]);
    OLED_ShowString(2, 6, show_str);
    
    sprintf(show_str, "%4.02f", change_mode[change_index]);
    OLED_ShowString(3, 1, show_str);
    
    switch (key_scan())
    {
    case 1 :
        if (args_mode[args_index] == ARG_FLOAT)
            *(float*)args[args_index] += (float)change_mode[change_index];
        if (args_mode[args_index] == ARG_INT)
            *(int*)args[args_index] += (int)change_mode[change_index];
        break;
    case 2 :
        if (args_mode[args_index] == ARG_FLOAT)
            *(float*)args[args_index] -= (float)change_mode[change_index];
        if (args_mode[args_index] == ARG_INT)
            *(int*)args[args_index] -= (int)change_mode[change_index];
        break;
    case 3 :
        change_index = (change_index + 1) % (sizeof(change_mode) / sizeof(change_mode[0]));
        break;
    case 4 :
        OLED_Clear();
        --menu_mode;
        break;
    }
}

void menu()
{
    switch (menu_mode)
    {
    case 0 :
        default_menu();
        break;
    case 1 :
        args_menu();
        break;
    case 2 :
        modify_args();
        break;
    }
}
